const { defineConfig } = require('@vue/cli-service')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const { info } = require('@vue/cli-shared-utils')
const ConfigGeneratePlugin = require('config-generate-plugin')
const dayjs = require('dayjs')
const pages = require('./src/pages')
const { genConfig, envPrefix, camelize } = require('./src/config/configGenerator')
const assetsDir = 'static'
const publicPath = process.env.VUE_APP_PUBLIC_PATH

const { ElementUiResolver } = require('unplugin-vue-components/resolvers')

function setEnv() {
  process.env.VUE_APP_OFFLINE = process.argv.includes('--offline') ? 'Y' : 'N'
  process.env.VUE_APP_APP_NAME = process.env.VUE_APP_APP_NAME || '首页'
}

if (process.env.VUE_APP_BUILD_DATE === 'Y') {
  process.env.VUE_APP_BUILD_DATE = dayjs(new Date()).format('YYYY-MM-DD HH:mm')
} else {
  process.env.VUE_APP_BUILD_DATE = ''
}

const components = [
  'EmptyView',
  'FormButton',
  'AwesomeButton',
  'ConfirmButton',
  'Confirmable',
  'PageSkeleton',
  'CustomScrollbar',
  'ElementDialog',
  'FlexColumn',
  'FlexItem',
  'FlexRow',
  'FlexScroller',
  'InputNumber',
  'LoadingView',
  'ErrorView',
  'FyCascader',
  'FyCheckbox',
  'FyCurd',
  'FyDate',
  'FyDynamic',
  'FyForm',
  'FyInput',
  'FyInputColor',
  'FyInputIcon',
  'FyInputMap',
  'FyInputNumber',
  'FyInputTable',
  'FyInputTree',
  'FyRadio',
  'FyRate',
  'FySelect',
  'FySlider',
  'FySwitch',
  'FyTime',
  'FyTitle',
  'FyUpload',
  'FyTree',
  'FyEmpty',
  'FyArray',
  'VueTreeSelect',
  'FyTabs',
  'DynamicTable',
  'FyFormDesign',
  'EasyPopup',
  'ResizeObserver',
  'NameAvatar',
  'FlowDesigner',
  'FlowViewer',
  'VueVideoPlayer',
  'VueCron',
  'VueQrCode',
  'IframeWindow',
  'DataDisplay',
  'TagRender',
  'SplitPane',
  'ContextMenu',
  'ResizeObserver',
  'Page',
  'Echarts',
  'VueQuillEditor'
]

const hyphenateRE = /\B([A-Z])/g

const hyphenate = (str, separator = '-') => {
  return str.replace(hyphenateRE, `${separator}$1`).toLowerCase()
}

function checkPublicPath() {
  if (publicPath && !publicPath.endsWith('/')) {
    throw new Error('APP_PUBLIC_PATH 必须以 / 结尾')
  }
}

function printEnv() {
  info('-------------------环境变量-------------------')
  info(`NODE_ENV=${process.env.NODE_ENV}`)
  Object.keys(process.env)
    .filter(key => key.startsWith(envPrefix))
    .forEach(key => {
      info(`${camelize(key.replace(envPrefix, '').toLowerCase(), '_')}=${process.env[key]}`)
    })
  info('---------------------------------------------')
}

setEnv()

printEnv()

checkPublicPath()

const gateway = 'http://192.168.0.107:9999'
const printService = 'http://192.168.0.225:888'
const pathRewrite = {
  [`^${process.env.VUE_APP_PUBLIC_PATH}`]: '/'
}

module.exports = defineConfig({
  assetsDir,
  publicPath: process.env.VUE_APP_PUBLIC_PATH,
  pages,
  productionSourceMap: false,
  lintOnSave: false,
  chainWebpack(config) {
    config.optimization.minimizer('terser').tap(args => {
      args[0].terserOptions.compress.drop_console = true
      return args
    })
  },
  configureWebpack() {
    const plugins = []
    if (process.env.VUE_APP_BUNDLE_ANALYZER === 'Y') {
      plugins.push(new BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: false }))
    }

    // 生成配置文件
    if (process.env.NODE_ENV === 'production') {
      plugins.push(new ConfigGeneratePlugin({ filename: 'config.json', config: genConfig() }))
    }

    plugins.push(
      require('unplugin-vue-components/webpack')({
        resolvers: [
          ElementUiResolver({ importStyle: false }),
          {
            type: 'component',
            resolve: name => {
              if (components.includes(name)) {
                const partialName = hyphenate(name)
                const sideEffects = [`@web-utils/component/base.css`]
                try {
                  require.resolve(`@web-utils/component/${partialName}/style.css`)
                  sideEffects.push(`@web-utils/component/${partialName}/style.css`)
                } catch (e) {
                  // 解析不到样式
                }
                return {
                  from: `@web-utils/component/${partialName}`,
                  sideEffects
                }
              }
            }
          }
        ]
      })
    )

    return {
      plugins,
      parallelism: 120,
      experiments: {
        backCompat: false
      },
      performance: {
        hints: process.env.NODE_ENV === 'production' ? 'warning' : false,
        maxAssetSize: 1024 * 1024 * 2,
        maxEntrypointSize: 1024 * 1024 * 2
      }
    }
  },
  css: {
    extract: process.env.NODE_ENV === 'production' ? { ignoreOrder: true } : false,
    loaderOptions: {
      sass: {
        additionalData: `@use "sass:math";
@import "~@/assets/styles/base/color.scss";
@import "~@/assets/styles/base/dimension.scss";
@import "~@/assets/styles/base/mixin.scss";`
      }
    }
  },
  devServer: {
    port: 6600,
    client: {
      overlay: false
    },
    proxy: {
      '/postek': {
        target: printService,
        pathRewrite,
        onProxyReq(proxyReq, req) {
          proxyReq.setHeader('origin', 'localhost')
          console.log(`[REQ] [${req.method}] ${printService}${req.url}`)
        }
      },
      '/preview-service': {
        target: 'http://192.168.0.107:30196',
        changeOrigin: true,
        pathRewrite
      },
      '/cloud-im-ws': {
        ws: true,
        target: gateway,
        changeOrigin: true,
        pathRewrite
      },
      '/': {
        ws: false,
        target: gateway,
        changeOrigin: true,
        pathRewrite,
        onProxyReq(proxyReq, req) {
          proxyReq.setHeader('origin', 'localhost')
          console.log(`[REQ] [${req.method}] ${gateway}${req.url}`)
        }
      }
    }
  }
})
